package clreqd_modules;
# vi:syntax=perl

#########################################################################
# This rountine takes one or more records packed on the command 	#
# line and applies them to the database table in question (which must	#
# already exist).							#
#									#
# Arguments are:							#
# table									#
# data									#
# [database]								#
# [truncate]								#
#									#
# truncate = 1 = empty table before adding new records.			#
# database  default is 'config' can be set to 'status'.			#
# The data is a packed hex string in the following format.		#
# 1 line = 1 record 							#
# line format is record|value...					#
#									#
# Treated as a single transaction - all changes made or none at all.	#
# No locking here since SQLite performs that.				#
#									#
# The input 'data' can be generated via teh converse dump_table		#
# request.								#
#########################################################################

use cldb;
use MIME::Base64;
use clmasterdefaults;
use Data::Dumper;
use clutils qw(to_bool);

sub load_table {
my %ARGS=@_;
my $f;

	if(!exists($ARGS{PREVIEW}))  { $ARGS{PREVIEW}=0; }
	if(!exists($ARGS{TRUNCATE})) { $ARGS{TRUNCATE}=0; }
	if(!exists($ARGS{DATABASE})) { $ARGS{DATABASE}="config"; }

	my $preview=to_bool($ARGS{PREVIEW});
	if(! -f "$::ENV{TRUECL_CFG}/$ARGS{DATABASE}.db") {
		return("FAIL Failed to open database '$::ENV{TRUECL_CFG}/$ARGS{DATABASE}.db'!");
	}

	#################################################################
	# Database does exist, so open it up ready for changing.	#
	#################################################################

	my $db=new cldb("$::ENV{TRUECL_CFG}/$ARGS{DATABASE}.db");
	if(!defined($db)) {
		return("FAIL Unable to open database '$ARGS{DATABASE}.db':\n" . cldb::error);
	}
	::msg("Opened database connection to '$::ENV{TRUECL_CFG}/$ARGS{DATABASE}.db'.");

	#################################################################
	# Ensure the table exists and abort if not.			#
	#################################################################

	if(! $db->exists("table","$ARGS{TABLE}")) {
		return("FAIL Config database missing '$ARGS{TABLE}' table.");
	}
	
	#################################################################
	# If the truncate = 1 then we need to start the transaction	#
	# and remove all existing records.				#
	#################################################################
	my $str="";

	if($ARGS{TRUNCATE}) {
		if($preview) {
			$str="DELETE FROM $ARGS{TABLE};\n";
		} else {
			$db->do("DELETE FROM $ARGS{TABLE};") or
				return "FAIL Unable to truncate table '$ARGS{TABLE}':\n" . ($db->error)[1];
		}
	}

	#################################################################
	# Now decode the data argument and treat each line as a 	#
	# separate insert.						#
	#################################################################
	my $data=decode_base64($ARGS{DATA});
	my @rows=split(/\n/,$data);

	my (@F,@fields,@values,$crow,$cmd);
	my $count=0;
	for $crow (@rows) {
		$cmd="INSERT OR REPLACE INTO $ARGS{TABLE} ";
		@fields=(); @values=();
		my $i=0;
		@F=split(/\|/,$crow);
		while($i<=$#F) {
			push @fields,$F[$i];
			if($i==$#F) {
				push @values,"''";
			} else {
				push @values, "'" . $F[$i+1] . "'";
			}
			$i+=2;
		}
		$cmd.="(" . join(",",@fields) . ") VALUES (" . join(",",@values) . ");";
		if($preview) {
			$str.="\n$cmd";
		} else {
			$db->do($cmd) or
				return "FAIL Unable to perform following insert:\n$cmd:\n" . ($db->error)[1];
			$count++;
		}
	}
	$db=undef;
	if($preview) {
		return "OK_RAWOUT\n$str";
	} else {
		return "OK $count";
	}
}

1;
